<!DOCTYPE html>
<html lang="zh-cn">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>贪吃蛇网页游戏</title>
    <style>
        body {
            background: linear-gradient(135deg, #e0f7fa 0%, #c8e6c9 100%);
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: flex-start;
            min-height: 100vh;
        }
        h1 {
            margin-top: 40px;
            font-family: 'Segoe UI', Arial, sans-serif;
            color: #2e7d32;
            letter-spacing: 2px;
            text-shadow: 1px 2px 8px #b2dfdb;
        }
        #gameCanvas {
            background: #fff;
            border: 3px solid #388e3c;
            margin-top: 20px;
            box-shadow: 0 8px 32px rgba(56,142,60,0.12), 0 1.5px 8px rgba(0,0,0,0.08);
            border-radius: 12px;
            transition: box-shadow 0.2s;
        }
        #gameCanvas:focus {
            outline: 2px solid #43a047;
            box-shadow: 0 0 0 4px #a5d6a7;
        }
        #score {
            font-size: 22px;
            margin-top: 16px;
            font-family: 'Consolas', monospace;
            color: #388e3c;
            background: rgba(255,255,255,0.7);
            padding: 4px 18px;
            border-radius: 8px;
            box-shadow: 0 1px 4px rgba(56,142,60,0.08);
        }
        #restartBtn {
            margin-top: 16px;
            padding: 8px 28px;
            font-size: 18px;
            border: none;
            background: linear-gradient(90deg, #43a047 0%, #66bb6a 100%);
            color: #fff;
            border-radius: 6px;
            cursor: pointer;
            font-weight: bold;
            letter-spacing: 1px;
            box-shadow: 0 2px 8px rgba(56,142,60,0.10);
            transition: background 0.2s, box-shadow 0.2s;
        }
        #restartBtn:hover {
            background: linear-gradient(90deg, #388e3c 0%, #43a047 100%);
            box-shadow: 0 4px 16px rgba(56,142,60,0.18);
        }
        @media (max-width: 500px) {
            #gameCanvas {
                width: 98vw !important;
                height: 98vw !important;
                max-width: 98vw;
                max-height: 98vw;
            }
            .ctrl-btn { width: 20vw; height: 20vw; font-size: 8vw; }
            #mobile-controls > div > div { width: 70vw !important; }
            /* 分数和排行榜按钮在小屏下也左右分布 */
            .score-rank-bar { width: 98vw !important; min-width: 0; }
        }
        .ctrl-btn {
            width: 80px;
            height: 80px;
            margin: 0;
            font-size: 38px;
            border: none;
            border-radius: 50%;
            background: linear-gradient(135deg, #a5d6a7 0%, #81c784 100%);
            color: #2e7d32;
            box-shadow: 0 2px 8px rgba(56,142,60,0.10);
            cursor: pointer;
            transition: background 0.2s, transform 0.1s;
            display: flex;
            align-items: center;
            justify-content: center;
            user-select: none;
        }
        .ctrl-btn:active {
            background: linear-gradient(135deg, #388e3c 0%, #66bb6a 100%);
            color: #fff;
            transform: scale(1.08);
        }
        #btn-up::after { content: '▲'; }
        #btn-down::after { content: '▼'; }
        #btn-left::after { content: '◀'; }
        #btn-right::after { content: '▶'; }
        #mobile-controls {
            width: 260px;
            margin: 0 auto;
        }
        #mobile-controls > div {
            width: 100%;
        }
        @media (max-width: 500px) {
            #mobile-controls { display: block !important; width: 98vw; }
        }
    </style>
</head>
<body>
    <h1>贪吃蛇网页游戏</h1>
    <div style="width:400px; max-width:96vw; display: flex; justify-content: space-between; align-items: center; margin: 0 auto 0 auto;">
        <div id="score">分数: 0</div>
        <button id="rankBtn" style="padding: 8px 18px; font-size: 18px; border: none; background: linear-gradient(90deg, #1976d2 0%, #42a5f5 100%); color: #fff; border-radius: 6px; cursor: pointer; font-weight: bold; letter-spacing: 1px; box-shadow: 0 2px 8px rgba(25,118,210,0.10); transition: background 0.2s, box-shadow 0.2s;">排行榜</button>
    </div>
    <canvas id="gameCanvas" width="400" height="400"></canvas>
    <div id="mobile-controls" style="display:none; margin-top:28px;">
        <div style="display:flex; flex-direction:column; align-items:center; gap:22px;">
            <button class="ctrl-btn" id="btn-up"></button>
            <div style="display:flex; flex-direction:row; justify-content:space-between; width:220px; gap:22px;">
                <button class="ctrl-btn" id="btn-left"></button>
                <button class="ctrl-btn" id="btn-down"></button>
                <button class="ctrl-btn" id="btn-right"></button>
            </div>
        </div>
    </div>
    <button id="restartBtn" style="display:none;">重新开始</button>
    
    <div id="rankModal" style="display:none;position:fixed;left:0;top:0;width:100vw;height:100vh;background:rgba(0,0,0,0.35);z-index:99;align-items:center;justify-content:center;">
        <div style="background:#fff;border-radius:12px;max-width:90vw;width:340px;padding:24px 18px 18px 18px;box-shadow:0 8px 32px rgba(56,142,60,0.12);position:relative;">
            <h2 style="margin:0 0 12px 0;font-size:22px;color:#388e3c;text-align:center;">排行榜</h2>
            <ol id="rankList" style="padding-left:22px;margin:0 0 12px 0;font-size:18px;color:#333;"></ol>
            <button id="closeRank" style="position:absolute;right:12px;top:12px;background:none;border:none;font-size:22px;color:#888;cursor:pointer;">×</button>
        </div>
    </div>

    <!-- 登录弹窗 -->
    <div id="loginModal" style="display:flex;position:fixed;left:0;top:0;width:100vw;height:100vh;background:rgba(0,0,0,0.35);z-index:100;align-items:center;justify-content:center;">
        <div style="background:#fff;border-radius:14px;max-width:90vw;width:340px;padding:32px 22px 24px 22px;box-shadow:0 8px 32px rgba(25,118,210,0.13);position:relative;display:flex;flex-direction:column;align-items:center;">
            <h2 style="margin:0 0 18px 0;font-size:24px;color:#1976d2;text-align:center;">登录</h2>
            <input id="loginName" type="text" placeholder="请输入昵称" maxlength="12" style="width:90%;padding:10px 12px;font-size:18px;border:1.5px solid #90caf9;border-radius:6px;margin-bottom:18px;outline:none;transition:border 0.2s;" onfocus="this.style.borderColor='#1976d2'" onblur="this.style.borderColor='#90caf9'">
            <button id="loginBtn" style="width:90%;padding:10px 0;font-size:18px;background:linear-gradient(90deg,#1976d2 0%,#42a5f5 100%);color:#fff;border:none;border-radius:6px;cursor:pointer;font-weight:bold;letter-spacing:1px;box-shadow:0 2px 8px rgba(25,118,210,0.10);transition:background 0.2s;">登录</button>
        </div>
    </div>

    <script>
        // =====================
        // 贪吃蛇游戏主逻辑
        // =====================
        const canvas = document.getElementById('gameCanvas');
        const ctx = canvas.getContext('2d');
        const box = 20; // 单格像素
        const row = canvas.width / box;
        const col = canvas.height / box;
        let snake, direction, food, score, gameInterval, isGameOver;

        // 涟漪效果参数
        let ripple = null;
        // 路径轨迹
        let pathTrail = [];
        const TRAIL_MAX = 20; // 最多显示20步

        // 初始化游戏
        function initGame() {
            snake = [
                { x: 8, y: 10 },
                { x: 7, y: 10 },
                { x: 6, y: 10 }
            ];
            direction = 'RIGHT';
            score = 0;
            isGameOver = false;
            document.getElementById('score').innerText = '分数: ' + score;
            document.getElementById('restartBtn').style.display = 'none';
            spawnFood();
            if (gameInterval) clearInterval(gameInterval);
            gameInterval = setInterval(gameLoop, 180); // 速度调慢，原120ms改为180ms
        }

        // 生成食物
        function spawnFood() {
            while (true) {
                food = {
                    x: Math.floor(Math.random() * row),
                    y: Math.floor(Math.random() * col)
                };
                // 食物不能生成在蛇身上
                if (!snake.some(seg => seg.x === food.x && seg.y === food.y)) break;
            }
        }

        // 监听键盘方向（支持方向键和WASD）
        document.addEventListener('keydown', e => {
            if (isGameOver) return;
            const key = e.key.toLowerCase();
            let changed = false;
            if ((e.key === 'ArrowUp' || key === 'w') && direction !== 'DOWN') { direction = 'UP'; changed = true; }
            else if ((e.key === 'ArrowDown' || key === 's') && direction !== 'UP') { direction = 'DOWN'; changed = true; }
            else if ((e.key === 'ArrowLeft' || key === 'a') && direction !== 'RIGHT') { direction = 'LEFT'; changed = true; }
            else if ((e.key === 'ArrowRight' || key === 'd') && direction !== 'LEFT') { direction = 'RIGHT'; changed = true; }
            if (changed) triggerRipple();
        });

        // 触屏按钮方向切换也加涟漪
        function addRippleToBtn(btn, dir) {
            btn.addEventListener('touchstart', function(e){
                e.preventDefault();
                let changed = false;
                if(dir==='UP' && direction!=='DOWN') { direction='UP'; changed=true; }
                if(dir==='DOWN' && direction!=='UP') { direction='DOWN'; changed=true; }
                if(dir==='LEFT' && direction!=='RIGHT') { direction='LEFT'; changed=true; }
                if(dir==='RIGHT' && direction!=='LEFT') { direction='RIGHT'; changed=true; }
                if(changed) triggerRipple();
            });
        }
        addRippleToBtn(document.getElementById('btn-up'), 'UP');
        addRippleToBtn(document.getElementById('btn-down'), 'DOWN');
        addRippleToBtn(document.getElementById('btn-left'), 'LEFT');
        addRippleToBtn(document.getElementById('btn-right'), 'RIGHT');

        // 触发涟漪效果
        function triggerRipple() {
            ripple = {
                x: snake[0].x * box + box/2,
                y: snake[0].y * box + box/2,
                radius: box/2,
                max: box*2.2,
                alpha: 0.5
            };
        }

        // 游戏主循环
        function gameLoop() {
            // 记录路径
            pathTrail.unshift({ x: snake[0].x, y: snake[0].y });
            if (pathTrail.length > TRAIL_MAX) pathTrail.pop();

            // 计算新头部
            const head = { ...snake[0] };
            if (direction === 'UP') head.y -= 1;
            if (direction === 'DOWN') head.y += 1;
            if (direction === 'LEFT') head.x -= 1;
            if (direction === 'RIGHT') head.x += 1;

            // 撞墙或撞自己判定
            if (
                head.x < 0 || head.x >= row ||
                head.y < 0 || head.y >= col ||
                snake.some(seg => seg.x === head.x && seg.y === head.y)
            ) {
                gameOver();
                return;
            }

            // 吃到食物
            if (head.x === food.x && head.y === food.y) {
                snake.unshift(head); // 增长
                score++;
                document.getElementById('score').innerText = '分数: ' + score;
                spawnFood();
            } else {
                snake.unshift(head);
                snake.pop(); // 移动
            }

            draw();
        }

        // 绘制游戏画面
        function draw() {
            ctx.clearRect(0, 0, canvas.width, canvas.height);
            // 绘制路径轨迹
            for(let i=pathTrail.length-1;i>=0;i--){
                const t = i/pathTrail.length;
                ctx.save();
                ctx.globalAlpha = 0.12 + 0.18 * (1-t);
                ctx.fillStyle = '#1976d2';
                ctx.beginPath();
                ctx.arc(pathTrail[i].x*box+box/2, pathTrail[i].y*box+box/2, box/2.5 + 2*t, 0, 2*Math.PI);
                ctx.fill();
                ctx.restore();
            }
            // 涟漪效果
            if(ripple){
                ctx.save();
                ctx.beginPath();
                ctx.arc(ripple.x, ripple.y, ripple.radius, 0, 2*Math.PI);
                ctx.strokeStyle = `rgba(33,150,243,${ripple.alpha})`;
                ctx.lineWidth = 6;
                ctx.shadowColor = '#90caf9';
                ctx.shadowBlur = 8;
                ctx.stroke();
                ctx.restore();
                ripple.radius += 6;
                ripple.alpha *= 0.92;
                if(ripple.radius > ripple.max || ripple.alpha < 0.05) ripple = null;
            }
            // 绘制蛇
            for (let i = 0; i < snake.length; i++) {
                ctx.fillStyle = i === 0 ? '#388e3c' : '#66bb6a';
                ctx.fillRect(snake[i].x * box, snake[i].y * box, box, box);
                ctx.strokeStyle = '#fff';
                ctx.strokeRect(snake[i].x * box, snake[i].y * box, box, box);
            }
            // 绘制食物
            ctx.fillStyle = '#e53935';
            ctx.beginPath();
            ctx.arc(food.x * box + box/2, food.y * box + box/2, box/2-2, 0, 2*Math.PI);
            ctx.fill();
        }

        // 游戏结束
        function gameOver() {
            clearInterval(gameInterval);
            isGameOver = true;
            document.getElementById('restartBtn').style.display = 'inline-block';
            ctx.fillStyle = 'rgba(0,0,0,0.5)';
            ctx.fillRect(0, canvas.height/2-40, canvas.width, 80);
            ctx.fillStyle = '#fff';
            ctx.font = '32px Arial';
            ctx.textAlign = 'center';
            ctx.fillText('游戏结束', canvas.width/2, canvas.height/2);
            ctx.font = '20px Arial';
            ctx.fillText('分数: ' + score, canvas.width/2, canvas.height/2+32);
            window.lastScore = score;
            saveScoreToServer(score);
        }

        // 登录相关（对接后端接口）
        async function registerUser(nickname) {
            // 注册接口
            const res = await fetch('http://www.ado.com/app/data/api/register', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({ nickname })
            });
            if (!res.ok) throw new Error('注册失败');
            return await res.json();
        }
        async function loginUser(nickname) {
            // 登录接口
            const res = await fetch('http://www.ado.com/app/data/api/login', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({ nickname })
            });
            if (!res.ok) throw new Error('登录失败');
            return await res.json();
        }
        function isLogin() {
            return !!localStorage.getItem('snakeUser');
        }
        function getLoginName() {
            return localStorage.getItem('snakeUser') || '';
        }
        function showLoginModal() {
            document.getElementById('loginModal').style.display = 'flex';
        }
        function hideLoginModal() {
            document.getElementById('loginModal').style.display = 'none';
        }
        document.getElementById('loginBtn').onclick = async function() {
            const name = document.getElementById('loginName').value.trim();
            if (!name) {
                document.getElementById('loginName').style.borderColor = '#e53935';
                document.getElementById('loginName').placeholder = '昵称不能为空';
                return;
            }
            try {
                await registerUser(name); // 注册
                await loginUser(name);    // 登录
                localStorage.setItem('snakeUser', name);
                hideLoginModal();
                startGameWithLogin();
            } catch (e) {
                alert(e.message || '登录失败');
            }
        };
        // 检查登录并启动游戏
        function startGameWithLogin() {
            if (!isLogin()) {
                showLoginModal();
                return;
            }
            initGame();
        }

        // 排行榜相关
        async function saveScoreToServer(score) {
            // 保存分数接口
            try {
                await fetch('http://www.ado.com/app/data/api/saveScore', {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify({ nickname: getLoginName(), score })
                });
            } catch (e) {
                console.warn('分数保存失败', e);
            }
        }
        async function fetchRankListFromServer() {
            // 获取排行榜接口
            try {
                const res = await fetch('http://www.ado.com/app/data/api/getRank');
                if (!res.ok) throw new Error('获取排行榜失败');
                return await res.json();
            } catch (e) {
                return [{ name: '暂无数据', score: 0 }];
            }
        }

        // 排行榜弹窗逻辑
        document.getElementById('rankBtn').onclick = async function() {
            document.getElementById('rankModal').style.display = 'flex';
            const list = document.getElementById('rankList');
            list.innerHTML = '<li>加载中...</li>';
            const arr = await fetchRankListFromServer();
            list.innerHTML = arr.map((item,i)=>`<li>${item.name}：<b style='color:#388e3c'>${item.score}</b></li>`).join('');
        };
        document.getElementById('closeRank').onclick = function() {
            document.getElementById('rankModal').style.display = 'none';
        };

        // 重新开始按钮
        document.getElementById('restartBtn').onclick = startGameWithLogin;

        // 触屏控制支持
        function showMobileControlsIfNeeded() {
            if (window.innerWidth <= 500 || 'ontouchstart' in window) {
                document.getElementById('mobile-controls').style.display = 'block';
            }
        }
        showMobileControlsIfNeeded();
        window.addEventListener('resize', showMobileControlsIfNeeded);

        // 绑定按钮事件
        document.getElementById('btn-up').addEventListener('touchstart', function(e){ e.preventDefault(); if(direction!=='DOWN') direction='UP'; });
        document.getElementById('btn-down').addEventListener('touchstart', function(e){ e.preventDefault(); if(direction!=='UP') direction='DOWN'; });
        document.getElementById('btn-left').addEventListener('touchstart', function(e){ e.preventDefault(); if(direction!=='RIGHT') direction='LEFT'; });
        document.getElementById('btn-right').addEventListener('touchstart', function(e){ e.preventDefault(); if(direction!=='LEFT') direction='RIGHT'; });

        // 启动时检测登录
        window.onload = function() {
            if (!isLogin()) {
                showLoginModal();
            } else {
                startGameWithLogin();
            }
        };
    </script>
</body>
</html>
